// Copyright 2008 David Mitchell
// Released under the MIT License

using System;
using System.Runtime.InteropServices;

namespace NSDuctTape
{
	internal sealed class HGlobal : IDisposable
	{
		public HGlobal(int size)
		{
			if (size <= 0)
				throw new ArgumentException("size", "size must be positive.");

			_hGlobal = Marshal.AllocHGlobal(size);
		}

		public static HGlobal StructureToHGlobal<T>(T value)
			where T : struct
		{
			HGlobal result = new HGlobal(Marshal.SizeOf(value));
			Marshal.StructureToPtr(value, result.ToIntPtr(), false);
			return result;
		}

		public static HGlobal StringToHGlobalAnsi(string value)
		{
			return new HGlobal(Marshal.StringToHGlobalAnsi(value));
		}

		public static HGlobal StringToHGlobalUni(string value)
		{
			return new HGlobal(Marshal.StringToHGlobalUni(value));
		}

		public IntPtr ToIntPtr()
		{
			if (_hGlobal == IntPtr.Zero)
				throw new ObjectDisposedException("DisposableHGlobal");

			return _hGlobal;
		}

		public void Dispose()
		{
			if (_hGlobal != IntPtr.Zero)
				Marshal.FreeHGlobal(_hGlobal);
			_hGlobal = IntPtr.Zero;
		}

		private HGlobal(IntPtr hGlobal)
		{
			_hGlobal = hGlobal;
		}

		IntPtr _hGlobal;
	}
}
